package fpsman;

import objects.Ball;
import objects.Player;
import objects.Ghost;
import com.jme3.app.SimpleApplication;
import com.jme3.asset.TextureKey;
import com.jme3.audio.AudioNode;
import com.jme3.bullet.BulletAppState;
import com.jme3.bullet.collision.PhysicsCollisionEvent;
import com.jme3.bullet.collision.PhysicsCollisionListener;
import com.jme3.bullet.collision.shapes.CapsuleCollisionShape;
import com.jme3.bullet.control.RigidBodyControl;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.light.DirectionalLight;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Vector2f;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.shape.Box;
import com.jme3.texture.Texture;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeMap;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author André
 */
public class Game extends SimpleApplication implements PhysicsCollisionListener, ActionListener {

    // <editor-fold defaultstate="collapsed" desc="Board">
    static int[][] board = {
        {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1},
        {1, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 7, 1},
        {1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1},
        {1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1},
        {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1},
        {1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1},
        {1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1},
        {1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1},
        {1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1},
        {1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1},
        {1, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 0, 0, 0, 0, 0, 1},
        {1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1},
        {1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1},
        {1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1},
        {1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1},
        {1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1},
        {1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1},
        {1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1},
        {1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1},
        {1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1},
        {1, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 1},
        {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}};
    //</editor-fold>
    private ArrayList<MyPath> paths;
    private Player player;
    private ArrayList<Ghost> ghosts;
    private Node balls, scene;
    private Material smat, bmat, fmat, spmat, cmat;
    private BulletAppState bulletAppState;
    private AudioNode eating, dies, siren;
    private int pontos;
    private Vector3f camDir = new Vector3f();
    private Vector3f camLeft = new Vector3f();
    private BitmapText pts;
    private Boolean playing = false, pause = false;
    private niftyController controller;
    private TreeMap<Integer, String> placar;
    private boolean soundPlay = true;

    public void startGame() {
        playing = true;
        loadBoard();
        pontos = 0;
        guiNode.attachChild(pts);
        MyMotionControl control;
        for (int i = 0; i < ghosts.size(); i++) {
            control = new MyMotionControl(ghosts.get(i).getModel(), paths.get(i));
            control.play();
        }
        player.setPhysicsLocation(new Vector3f(9f, 1.2f, -4.5f));
        siren.play();
    }

    //<editor-fold defaultstate="collapsed" desc="Loads">
    private void loadBoard() {
        ghosts = new ArrayList<Ghost>();
        for (int i = 0; i < 22; i++) {
            for (int j = 0; j < 19; j++) {
                if (board[i][j] == 1) {
                    Geometry geom = getBrick("Brick" + i + j, new Vector3f(1.5f + j * 3, 2, -1.5f - i * 3));
                    scene.attachChild(geom);
                } else if (board[i][j] == 2) {
                    for (int z = 0; z < 4; z++) {
                        ghosts.add(getGhost("Ghost" + z, new Vector3f(1.5f + j * 3, 0.3f, -1.5f - i * 3)));
                    }
                } else {
                    Geometry geom = getSphere("Sphere" + i + j, new Vector3f(1.5f + j * 3, 0.5f, -1.5f - i * 3), board[i][j] == 7);
                    balls.attachChild(geom);
                }
            }
        }
    }

    private void loadPlayer() {
        CapsuleCollisionShape capsuleShape = new CapsuleCollisionShape(1.1f, 1f, 1);
        player = new Player("Pacman", capsuleShape, 0f);
        bulletAppState.getPhysicsSpace().add(player);
    }

    private void loadScene() {
        balls = new Node();
        scene = new Node();
        scene.attachChild(getFloor());
        scene.attachChild(getCeil());
        rootNode.attachChild(balls);
        rootNode.attachChild(scene);
    }

    private void loadMaterials() {
        bmat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        Texture tex = assetManager.loadTexture("Textures/Concrete_Wall.PNG");
        bmat.setTexture("ColorMap", tex);
        smat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        smat.setColor("Color", ColorRGBA.Blue);
        spmat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        spmat.setColor("Color", ColorRGBA.Yellow);
        fmat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        TextureKey key3 = new TextureKey("Textures/floor.jpg");
        key3.setGenerateMips(true);
        Texture tex3 = assetManager.loadTexture(key3);
        tex3.setWrap(Texture.WrapMode.Repeat);
        fmat.setTexture("ColorMap", tex3);
        cmat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
        key3 = new TextureKey("Textures/sky.jpg");
        key3.setGenerateMips(true);
        tex3 = assetManager.loadTexture(key3);
        tex3.setWrap(Texture.WrapMode.Repeat);
        cmat.setTexture("ColorMap", tex3);
    }

    private void loadPhysics() {
        bulletAppState = new BulletAppState();
        stateManager.attach(bulletAppState);
        bulletAppState.getPhysicsSpace().addCollisionListener(this);
    }

    private void loadPaths() {
        paths = new ArrayList<>();
        paths.add(new MyPath());
        paths.get(0).addWayPoint(new Vector3f(28.5f, 0.1f, -31.5f));
        paths.get(0).addWayPoint(new Vector3f(28.5f, 0.1f, -25.5f));

        paths.add(new MyPath());
        paths.get(1).addWayPoint(new Vector3f(28.5f, 0.1f, -25.5f));
        paths.get(1).addWayPoint(new Vector3f(31.5f, 0.1f, -25.5f));

        paths.add(new MyPath());
        paths.get(2).addWayPoint(new Vector3f(28.5f, 0.1f, -25.5f));
        paths.get(2).addWayPoint(new Vector3f(25.5f, 0.1f, -25.5f));

        paths.add(new MyPath());
        paths.get(3).addWayPoint(new Vector3f(31.5f, 0.1f, -25.5f));
        paths.get(3).addWayPoint(new Vector3f(31.5f, 0.1f, -19.5f));
        paths.get(3).addWayPoint(new Vector3f(37.5f, 0.1f, -19.5f));
        paths.get(3).addWayPoint(new Vector3f(37.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(4).addWayPoint(new Vector3f(25.5f, 0.1f, -25.5f));
        paths.get(4).addWayPoint(new Vector3f(25.5f, 0.1f, -19.5f));
        paths.get(4).addWayPoint(new Vector3f(19.5f, 0.1f, -19.5f));
        paths.get(4).addWayPoint(new Vector3f(19.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(5).addWayPoint(new Vector3f(31.5f, 0.1f, -25.5f));
        paths.get(5).addWayPoint(new Vector3f(37.5f, 0.1f, -25.5f));
        paths.get(5).addWayPoint(new Vector3f(37.5f, 0.1f, -31.5f));

        paths.add(new MyPath());
        paths.get(6).addWayPoint(new Vector3f(25.5f, 0.1f, -25.5f));
        paths.get(6).addWayPoint(new Vector3f(19.5f, 0.1f, -25.5f));
        paths.get(6).addWayPoint(new Vector3f(19.5f, 0.1f, -31.5f));

        paths.add(new MyPath());
        paths.get(7).addWayPoint(new Vector3f(37.5f, 0.1f, -13.5f));
        paths.get(7).addWayPoint(new Vector3f(43.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(8).addWayPoint(new Vector3f(19.5f, 0.1f, -13.5f));
        paths.get(8).addWayPoint(new Vector3f(13.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(9).addWayPoint(new Vector3f(37.5f, 0.1f, -13.5f));
        paths.get(9).addWayPoint(new Vector3f(31.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(10).addWayPoint(new Vector3f(19.5f, 0.1f, -13.5f));
        paths.get(10).addWayPoint(new Vector3f(25.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(11).addWayPoint(new Vector3f(37.5f, 0.1f, -31.5f));
        paths.get(11).addWayPoint(new Vector3f(43.5f, 0.1f, -31.5f));

        paths.add(new MyPath());
        paths.get(12).addWayPoint(new Vector3f(19.5f, 0.1f, -31.5f));
        paths.get(12).addWayPoint(new Vector3f(19.5f, 0.1f, -37.5f));

        paths.add(new MyPath());
        paths.get(13).addWayPoint(new Vector3f(37.5f, 0.1f, -31.5f));
        paths.get(13).addWayPoint(new Vector3f(37.5f, 0.1f, -37.5f));

        paths.add(new MyPath());
        paths.get(14).addWayPoint(new Vector3f(19.5f, 0.1f, -31.5f));
        paths.get(14).addWayPoint(new Vector3f(13.5f, 0.1f, -31.5f));

        paths.add(new MyPath());
        paths.get(15).addWayPoint(new Vector3f(43.5f, 0.1f, -13.5f));
        paths.get(15).addWayPoint(new Vector3f(43.5f, 0.1f, -4.5f));

        paths.add(new MyPath());
        paths.get(16).addWayPoint(new Vector3f(13.5f, 0.1f, -13.5f));
        paths.get(16).addWayPoint(new Vector3f(4.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(17).addWayPoint(new Vector3f(43.5f, 0.1f, -13.5f));
        paths.get(17).addWayPoint(new Vector3f(43.5f, 0.1f, -22.5f));

        paths.add(new MyPath());
        paths.get(18).addWayPoint(new Vector3f(13.5f, 0.1f, -13.5f));
        paths.get(18).addWayPoint(new Vector3f(13.5f, 0.1f, -4.5f));

        paths.add(new MyPath());
        paths.get(19).addWayPoint(new Vector3f(43.5f, 0.1f, -13.5f));
        paths.get(19).addWayPoint(new Vector3f(52.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(20).addWayPoint(new Vector3f(13.5f, 0.1f, -13.5f));
        paths.get(20).addWayPoint(new Vector3f(13.5f, 0.1f, -22.5f));

        paths.add(new MyPath());
        paths.get(21).addWayPoint(new Vector3f(31.5f, 0.1f, -13.5f));
        paths.get(21).addWayPoint(new Vector3f(25.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(22).addWayPoint(new Vector3f(25.5f, 0.1f, -13.5f));
        paths.get(22).addWayPoint(new Vector3f(31.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(23).addWayPoint(new Vector3f(31.5f, 0.1f, -13.5f));
        paths.get(23).addWayPoint(new Vector3f(31.5f, 0.1f, -4.5f));
        paths.get(23).addWayPoint(new Vector3f(43.5f, 0.1f, -4.5f));

        paths.add(new MyPath());
        paths.get(24).addWayPoint(new Vector3f(25.5f, 0.1f, -13.5f));
        paths.get(24).addWayPoint(new Vector3f(25.5f, 0.1f, -4.5f));
        paths.get(24).addWayPoint(new Vector3f(13.5f, 0.1f, -4.5f));

        paths.add(new MyPath());
        paths.get(25).addWayPoint(new Vector3f(43.5f, 0.1f, -31.5f));
        paths.get(25).addWayPoint(new Vector3f(43.5f, 0.1f, -43.5f));

        paths.add(new MyPath());
        paths.get(26).addWayPoint(new Vector3f(19.5f, 0.1f, -37.5f));
        paths.get(26).addWayPoint(new Vector3f(37.5f, 0.1f, -37.5f));

        paths.add(new MyPath());
        paths.get(27).addWayPoint(new Vector3f(43.5f, 0.1f, -31.5f));
        paths.get(27).addWayPoint(new Vector3f(43.5f, 0.1f, -22.5f));
        paths.add(new MyPath());
        paths.get(28).addWayPoint(new Vector3f(19.5f, 0.1f, -37.5f));
        paths.get(28).addWayPoint(new Vector3f(19.5f, 0.1f, -43.5f));
        paths.add(new MyPath());
        paths.get(29).addWayPoint(new Vector3f(43.5f, 0.1f, -31.5f));
        paths.get(29).addWayPoint(new Vector3f(52.5f, 0.1f, -31.5f));
        paths.add(new MyPath());
        paths.get(30).addWayPoint(new Vector3f(13.5f, 0.1f, -31.5f));
        paths.get(30).addWayPoint(new Vector3f(4.5f, 0.1f, -31.5f));
        paths.add(new MyPath());
        paths.get(31).addWayPoint(new Vector3f(37.5f, 0.1f, -37.5f));
        paths.get(31).addWayPoint(new Vector3f(19.5f, 0.1f, -37.5f));
        paths.add(new MyPath());
        paths.get(32).addWayPoint(new Vector3f(13.5f, 0.1f, -31.5f));
        paths.get(32).addWayPoint(new Vector3f(13.5f, 0.1f, -43.5f));
        paths.add(new MyPath());
        paths.get(33).addWayPoint(new Vector3f(37.5f, 0.1f, -37.5f));
        paths.get(33).addWayPoint(new Vector3f(37.5f, 0.1f, -43.5f));
        paths.add(new MyPath());
        paths.get(34).addWayPoint(new Vector3f(13.5f, 0.1f, -31.5f));
        paths.get(34).addWayPoint(new Vector3f(13.5f, 0.1f, -22.5f));
        paths.add(new MyPath());
        paths.get(35).addWayPoint(new Vector3f(43.5f, 0.1f, -4.5f));
        paths.get(35).addWayPoint(new Vector3f(52.5f, 0.1f, -4.5f));
        paths.get(35).addWayPoint(new Vector3f(52.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(36).addWayPoint(new Vector3f(4.5f, 0.1f, -13.5f));
        paths.get(36).addWayPoint(new Vector3f(4.5f, 0.1f, -4.5f));
        paths.get(36).addWayPoint(new Vector3f(13.5f, 0.1f, -4.5f));
        paths.add(new MyPath());
        paths.get(37).addWayPoint(new Vector3f(43.5f, 0.1f, -4.5f));
        paths.get(37).addWayPoint(new Vector3f(31.5f, 0.1f, -4.5f));
        paths.get(37).addWayPoint(new Vector3f(31.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(38).addWayPoint(new Vector3f(4.5f, 0.1f, -13.5f));
        paths.get(38).addWayPoint(new Vector3f(4.5f, 0.1f, -22.5f));
        paths.get(38).addWayPoint(new Vector3f(13.5f, 0.1f, -22.5f));
        paths.add(new MyPath());
        paths.get(39).addWayPoint(new Vector3f(43.5f, 0.1f, -22.5f));
        paths.get(39).addWayPoint(new Vector3f(52.5f, 0.1f, -22.5f));
        paths.get(39).addWayPoint(new Vector3f(52.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(40).addWayPoint(new Vector3f(13.5f, 0.1f, -4.5f));
        paths.get(40).addWayPoint(new Vector3f(4.5f, 0.1f, -4.5f));
        paths.get(40).addWayPoint(new Vector3f(4.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(41).addWayPoint(new Vector3f(43.5f, 0.1f, -22.5f));
        paths.get(41).addWayPoint(new Vector3f(43.5f, 0.1f, -31.5f));
        paths.add(new MyPath());
        paths.get(42).addWayPoint(new Vector3f(13.5f, 0.1f, -4.5f));
        paths.get(42).addWayPoint(new Vector3f(25.5f, 0.1f, -4.5f));
        paths.get(42).addWayPoint(new Vector3f(25.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(43).addWayPoint(new Vector3f(52.5f, 0.1f, -13.5f));
        paths.get(43).addWayPoint(new Vector3f(52.5f, 0.1f, -4.5f));
        paths.get(43).addWayPoint(new Vector3f(43.5f, 0.1f, -4.5f));
        paths.add(new MyPath());
        paths.get(44).addWayPoint(new Vector3f(13.5f, 0.1f, -22.5f));
        paths.get(44).addWayPoint(new Vector3f(4.5f, 0.1f, -22.5f));
        paths.get(44).addWayPoint(new Vector3f(4.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(45).addWayPoint(new Vector3f(52.5f, 0.1f, -13.5f));
        paths.get(45).addWayPoint(new Vector3f(52.5f, 0.1f, -22.5f));
        paths.get(45).addWayPoint(new Vector3f(43.5f, 0.1f, -22.5f));
        paths.add(new MyPath());
        paths.get(46).addWayPoint(new Vector3f(13.5f, 0.1f, -22.5f));
        paths.get(46).addWayPoint(new Vector3f(13.5f, 0.1f, -31.5f));
        paths.add(new MyPath());
        paths.get(47).addWayPoint(new Vector3f(25.5f, 0.1f, -13.5f));
        paths.get(47).addWayPoint(new Vector3f(19.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(48).addWayPoint(new Vector3f(31.5f, 0.1f, -13.5f));
        paths.get(48).addWayPoint(new Vector3f(37.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(49).addWayPoint(new Vector3f(43.5f, 0.1f, -4.5f));
        paths.get(49).addWayPoint(new Vector3f(43.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(50).addWayPoint(new Vector3f(13.5f, 0.1f, -4.5f));
        paths.get(50).addWayPoint(new Vector3f(13.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(51).addWayPoint(new Vector3f(43.5f, 0.1f, -43.5f));
        paths.get(51).addWayPoint(new Vector3f(52.5f, 0.1f, -43.5f));
        paths.get(51).addWayPoint(new Vector3f(52.5f, 0.1f, -49.5f));
        paths.get(51).addWayPoint(new Vector3f(49.5f, 0.1f, -49.5f));
        paths.get(51).addWayPoint(new Vector3f(49.5f, 0.1f, -55.5f));
        paths.add(new MyPath());
        paths.get(52).addWayPoint(new Vector3f(37.5f, 0.1f, -37.5f));
        paths.get(52).addWayPoint(new Vector3f(37.5f, 0.1f, -31.5f));
        paths.add(new MyPath());
        paths.get(53).addWayPoint(new Vector3f(43.5f, 0.1f, -43.5f));
        paths.get(53).addWayPoint(new Vector3f(43.5f, 0.1f, -49.5f));
        paths.add(new MyPath());
        paths.get(54).addWayPoint(new Vector3f(19.5f, 0.1f, -43.5f));
        paths.get(54).addWayPoint(new Vector3f(25.5f, 0.1f, -43.5f));
        paths.get(54).addWayPoint(new Vector3f(25.5f, 0.1f, -49.5f));
        paths.add(new MyPath());
        paths.get(55).addWayPoint(new Vector3f(43.5f, 0.1f, -22.5f));
        paths.get(55).addWayPoint(new Vector3f(43.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(56).addWayPoint(new Vector3f(19.5f, 0.1f, -43.5f));
        paths.get(56).addWayPoint(new Vector3f(13.5f, 0.1f, -43.5f));
        paths.add(new MyPath());
        paths.get(57).addWayPoint(new Vector3f(52.5f, 0.1f, -31.5f));
        paths.get(57).addWayPoint(new Vector3f(43.5f, 0.1f, -31.5f));
        paths.add(new MyPath());
        paths.get(58).addWayPoint(new Vector3f(4.5f, 0.1f, -31.5f));
        paths.get(58).addWayPoint(new Vector3f(13.5f, 0.1f, -31.5f));

        paths.add(new MyPath());
        paths.get(59).addWayPoint(new Vector3f(19.5f, 0.1f, -37.5f));
        paths.get(59).addWayPoint(new Vector3f(19.5f, 0.1f, -31.5f));

        paths.add(new MyPath());
        paths.get(60).addWayPoint(new Vector3f(13.5f, 0.1f, -43.5f));
        paths.get(60).addWayPoint(new Vector3f(13.5f, 0.1f, -49.5f));

        paths.add(new MyPath());
        paths.get(61).addWayPoint(new Vector3f(37.5f, 0.1f, -43.5f));
        paths.get(61).addWayPoint(new Vector3f(43.5f, 0.1f, -43.5f));

        paths.add(new MyPath());
        paths.get(62).addWayPoint(new Vector3f(13.5f, 0.1f, -43.5f));
        paths.get(62).addWayPoint(new Vector3f(4.5f, 0.1f, -43.5f));
        paths.get(62).addWayPoint(new Vector3f(4.5f, 0.1f, -49.5f));
        paths.get(62).addWayPoint(new Vector3f(7.5f, 0.1f, -49.5f));
        paths.get(62).addWayPoint(new Vector3f(7.5f, 0.1f, -55.5f));

        paths.add(new MyPath());
        paths.get(63).addWayPoint(new Vector3f(37.5f, 0.1f, -43.5f));
        paths.get(63).addWayPoint(new Vector3f(31.5f, 0.1f, -43.5f));
        paths.get(63).addWayPoint(new Vector3f(31.5f, 0.1f, -49.5f));

        paths.add(new MyPath());
        paths.get(64).addWayPoint(new Vector3f(13.5f, 0.1f, -22.5f));
        paths.get(64).addWayPoint(new Vector3f(13.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(65).addWayPoint(new Vector3f(52.5f, 0.1f, -13.5f));
        paths.get(65).addWayPoint(new Vector3f(43.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(66).addWayPoint(new Vector3f(4.5f, 0.1f, -13.5f));
        paths.get(66).addWayPoint(new Vector3f(13.5f, 0.1f, -13.5f));

        paths.add(new MyPath());
        paths.get(67).addWayPoint(new Vector3f(19.5f, 0.1f, -13.5f));
        paths.get(67).addWayPoint(new Vector3f(19.5f, 0.1f, -19.5f));
        paths.get(67).addWayPoint(new Vector3f(25.5f, 0.1f, -19.5f));
        paths.get(67).addWayPoint(new Vector3f(25.5f, 0.1f, -25.5f));

        paths.add(new MyPath());
        paths.get(68).addWayPoint(new Vector3f(37.5f, 0.1f, -13.5f));
        paths.get(68).addWayPoint(new Vector3f(37.5f, 0.1f, -19.5f));
        paths.get(68).addWayPoint(new Vector3f(31.5f, 0.1f, -19.5f));
        paths.get(68).addWayPoint(new Vector3f(31.5f, 0.1f, -25.5f));

        paths.add(new MyPath());
        paths.get(69).addWayPoint(new Vector3f(49.5f, 0.1f, -55.5f));
        paths.get(69).addWayPoint(new Vector3f(52.5f, 0.1f, -55.5f));
        paths.get(69).addWayPoint(new Vector3f(52.5f, 0.1f, -61.5f));
        paths.get(69).addWayPoint(new Vector3f(31.5f, 0.1f, -61.5f));

        paths.add(new MyPath());
        paths.get(70).addWayPoint(new Vector3f(37.5f, 0.1f, -31.5f));
        paths.get(70).addWayPoint(new Vector3f(37.5f, 0.1f, -25.5f));
        paths.get(70).addWayPoint(new Vector3f(31.5f, 0.1f, -25.5f));

        paths.add(new MyPath());
        paths.get(71).addWayPoint(new Vector3f(49.5f, 0.1f, -55.5f));
        paths.get(71).addWayPoint(new Vector3f(43.5f, 0.1f, -55.5f));
        paths.get(71).addWayPoint(new Vector3f(43.5f, 0.1f, -49.5f));

        paths.add(new MyPath());
        paths.get(72).addWayPoint(new Vector3f(25.5f, 0.1f, -49.5f));
        paths.get(72).addWayPoint(new Vector3f(31.5f, 0.1f, -49.5f));

        paths.add(new MyPath());
        paths.get(73).addWayPoint(new Vector3f(43.5f, 0.1f, -49.5f));
        paths.get(73).addWayPoint(new Vector3f(37.5f, 0.1f, -49.5f));

        paths.add(new MyPath());
        paths.get(74).addWayPoint(new Vector3f(25.5f, 0.1f, -49.5f));
        paths.get(74).addWayPoint(new Vector3f(19.5f, 0.1f, -49.5f));

        paths.add(new MyPath());
        paths.get(75).addWayPoint(new Vector3f(43.5f, 0.1f, -49.5f));
        paths.get(75).addWayPoint(new Vector3f(43.5f, 0.1f, -55.5f));
        paths.get(75).addWayPoint(new Vector3f(49.5f, 0.1f, -55.5f));

        paths.add(new MyPath());
        paths.get(76).addWayPoint(new Vector3f(13.5f, 0.1f, -43.5f));
        paths.get(76).addWayPoint(new Vector3f(13.5f, 0.1f, -31.5f));

        paths.add(new MyPath());
        paths.get(77).addWayPoint(new Vector3f(43.5f, 0.1f, -31.5f));
        paths.get(77).addWayPoint(new Vector3f(37.5f, 0.1f, -31.5f));

        paths.add(new MyPath());
        paths.get(78).addWayPoint(new Vector3f(13.5f, 0.1f, -31.5f));
        paths.get(78).addWayPoint(new Vector3f(19.5f, 0.1f, -31.5f));

        paths.add(new MyPath());
        paths.get(79).addWayPoint(new Vector3f(19.5f, 0.1f, -31.5f));
        paths.get(79).addWayPoint(new Vector3f(19.5f, 0.1f, -25.5f));
        paths.get(79).addWayPoint(new Vector3f(25.5f, 0.1f, -25.5f));

        paths.add(new MyPath());
        paths.get(80).addWayPoint(new Vector3f(13.5f, 0.1f, -49.5f));
        paths.get(80).addWayPoint(new Vector3f(19.5f, 0.1f, -49.5f));

        paths.add(new MyPath());
        paths.get(81).addWayPoint(new Vector3f(43.5f, 0.1f, -43.5f));
        paths.get(81).addWayPoint(new Vector3f(43.5f, 0.1f, -31.5f));

        paths.add(new MyPath());
        paths.get(82).addWayPoint(new Vector3f(13.5f, 0.1f, -49.5f));
        paths.get(82).addWayPoint(new Vector3f(13.5f, 0.1f, -55.5f));
        paths.get(82).addWayPoint(new Vector3f(7.5f, 0.1f, -55.5f));

        paths.add(new MyPath());
        paths.get(83).addWayPoint(new Vector3f(7.5f, 0.1f, -55.5f));
        paths.get(83).addWayPoint(new Vector3f(4.5f, 0.1f, -55.5f));
        paths.get(83).addWayPoint(new Vector3f(4.5f, 0.1f, -61.5f));
        paths.get(83).addWayPoint(new Vector3f(25.5f, 0.1f, -61.5f));

        paths.add(new MyPath());
        paths.get(84).addWayPoint(new Vector3f(7.5f, 0.1f, -55.5f));
        paths.get(84).addWayPoint(new Vector3f(13.5f, 0.1f, -55.5f));
        paths.get(84).addWayPoint(new Vector3f(13.5f, 0.1f, -49.5f));

        paths.add(new MyPath());
        paths.get(85).addWayPoint(new Vector3f(31.5f, 0.1f, -49.5f));
        paths.get(85).addWayPoint(new Vector3f(37.5f, 0.1f, -49.5f));

        paths.add(new MyPath());
        paths.get(86).addWayPoint(new Vector3f(31.5f, 0.1f, -49.5f));
        paths.get(86).addWayPoint(new Vector3f(25.5f, 0.1f, -49.5f));
        paths.add(new MyPath());
        paths.get(87).addWayPoint(new Vector3f(13.5f, 0.1f, -13.5f));
        paths.get(87).addWayPoint(new Vector3f(19.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(88).addWayPoint(new Vector3f(43.5f, 0.1f, -13.5f));
        paths.get(88).addWayPoint(new Vector3f(37.5f, 0.1f, -13.5f));
        paths.add(new MyPath());
        paths.get(89).addWayPoint(new Vector3f(25.5f, 0.1f, -25.5f));
        paths.get(89).addWayPoint(new Vector3f(28.5f, 0.1f, -25.5f));
        paths.add(new MyPath());
        paths.get(90).addWayPoint(new Vector3f(31.5f, 0.1f, -25.5f));
        paths.get(90).addWayPoint(new Vector3f(28.5f, 0.1f, -25.5f));
        paths.add(new MyPath());
        paths.get(91).addWayPoint(new Vector3f(31.5f, 0.1f, -61.5f));
        paths.get(91).addWayPoint(new Vector3f(31.5f, 0.1f, -55.5f));
        paths.get(91).addWayPoint(new Vector3f(37.5f, 0.1f, -55.5f));
        paths.get(91).addWayPoint(new Vector3f(37.5f, 0.1f, -49.5f));
        paths.add(new MyPath());
        paths.get(92).addWayPoint(new Vector3f(31.5f, 0.1f, -61.5f));
        paths.get(92).addWayPoint(new Vector3f(25.5f, 0.1f, -61.5f));
        paths.add(new MyPath());
        paths.get(93).addWayPoint(new Vector3f(43.5f, 0.1f, -49.5f));
        paths.get(93).addWayPoint(new Vector3f(43.5f, 0.1f, -43.5f));
        paths.add(new MyPath());
        paths.get(94).addWayPoint(new Vector3f(31.5f, 0.1f, -49.5f));
        paths.get(94).addWayPoint(new Vector3f(31.5f, 0.1f, -43.5f));
        paths.get(94).addWayPoint(new Vector3f(37.5f, 0.1f, -43.5f));
        paths.add(new MyPath());
        paths.get(95).addWayPoint(new Vector3f(37.5f, 0.1f, -49.5f));
        paths.get(95).addWayPoint(new Vector3f(31.5f, 0.1f, -49.5f));
        paths.add(new MyPath());
        paths.get(96).addWayPoint(new Vector3f(37.5f, 0.1f, -49.5f));
        paths.get(96).addWayPoint(new Vector3f(37.5f, 0.1f, -55.5f));
        paths.get(96).addWayPoint(new Vector3f(31.5f, 0.1f, -55.5f));
        paths.get(96).addWayPoint(new Vector3f(31.5f, 0.1f, -61.5f));

        loadNeighborhood();
    }

    private void loadNeighborhood() {
        paths.get(0).addNeighbor(paths.get(1));
        paths.get(0).addNeighbor(paths.get(2));
        paths.get(1).addNeighbor(paths.get(3));
        paths.get(1).addNeighbor(paths.get(5));
        paths.get(2).addNeighbor(paths.get(4));
        paths.get(2).addNeighbor(paths.get(6));
        paths.get(3).addNeighbor(paths.get(7));
        paths.get(3).addNeighbor(paths.get(9));
        paths.get(4).addNeighbor(paths.get(8));
        paths.get(4).addNeighbor(paths.get(10));
        paths.get(5).addNeighbor(paths.get(11));
        paths.get(5).addNeighbor(paths.get(13));
        paths.get(6).addNeighbor(paths.get(12));
        paths.get(6).addNeighbor(paths.get(14));
        paths.get(7).addNeighbor(paths.get(15));
        paths.get(7).addNeighbor(paths.get(17));
        paths.get(7).addNeighbor(paths.get(19));
        paths.get(8).addNeighbor(paths.get(16));
        paths.get(8).addNeighbor(paths.get(18));
        paths.get(8).addNeighbor(paths.get(20));
        paths.get(9).addNeighbor(paths.get(21));
        paths.get(9).addNeighbor(paths.get(23));
        paths.get(10).addNeighbor(paths.get(22));
        paths.get(10).addNeighbor(paths.get(24));
        paths.get(11).addNeighbor(paths.get(25));
        paths.get(11).addNeighbor(paths.get(27));
        paths.get(11).addNeighbor(paths.get(29));
        paths.get(12).addNeighbor(paths.get(26));
        paths.get(12).addNeighbor(paths.get(28));
        paths.get(13).addNeighbor(paths.get(31));
        paths.get(13).addNeighbor(paths.get(33));
        paths.get(14).addNeighbor(paths.get(30));
        paths.get(14).addNeighbor(paths.get(32));
        paths.get(14).addNeighbor(paths.get(34));
        paths.get(15).addNeighbor(paths.get(35));
        paths.get(15).addNeighbor(paths.get(37));
        paths.get(16).addNeighbor(paths.get(36));
        paths.get(16).addNeighbor(paths.get(38));
        paths.get(17).addNeighbor(paths.get(39));
        paths.get(17).addNeighbor(paths.get(41));
        paths.get(18).addNeighbor(paths.get(40));
        paths.get(18).addNeighbor(paths.get(42));
        paths.get(19).addNeighbor(paths.get(43));
        paths.get(19).addNeighbor(paths.get(45));
        paths.get(20).addNeighbor(paths.get(44));
        paths.get(20).addNeighbor(paths.get(46));
        paths.get(21).addNeighbor(paths.get(24));
        paths.get(21).addNeighbor(paths.get(47));
        paths.get(22).addNeighbor(paths.get(23));
        paths.get(22).addNeighbor(paths.get(48));
        paths.get(23).addNeighbor(paths.get(35));
        paths.get(23).addNeighbor(paths.get(49));
        paths.get(24).addNeighbor(paths.get(40));
        paths.get(24).addNeighbor(paths.get(50));
        paths.get(25).addNeighbor(paths.get(51));
        paths.get(25).addNeighbor(paths.get(53));
        paths.get(26).addNeighbor(paths.get(33));
        paths.get(26).addNeighbor(paths.get(52));
        paths.get(27).addNeighbor(paths.get(39));
        paths.get(27).addNeighbor(paths.get(55));
        paths.get(28).addNeighbor(paths.get(54));
        paths.get(28).addNeighbor(paths.get(56));
        paths.get(29).addNeighbor(paths.get(57));
        paths.get(30).addNeighbor(paths.get(58));
        paths.get(31).addNeighbor(paths.get(28));
        paths.get(31).addNeighbor(paths.get(59));
        paths.get(32).addNeighbor(paths.get(60));
        paths.get(32).addNeighbor(paths.get(62));
        paths.get(33).addNeighbor(paths.get(61));
        paths.get(33).addNeighbor(paths.get(63));
        paths.get(34).addNeighbor(paths.get(44));
        paths.get(34).addNeighbor(paths.get(64));
        paths.get(35).addNeighbor(paths.get(45));
        paths.get(35).addNeighbor(paths.get(65));
        paths.get(36).addNeighbor(paths.get(42));
        paths.get(36).addNeighbor(paths.get(50));
        paths.get(37).addNeighbor(paths.get(21));
        paths.get(37).addNeighbor(paths.get(48));
        paths.get(38).addNeighbor(paths.get(46));
        paths.get(38).addNeighbor(paths.get(64));
        paths.get(39).addNeighbor(paths.get(43));
        paths.get(39).addNeighbor(paths.get(65));
        paths.get(40).addNeighbor(paths.get(38));
        paths.get(40).addNeighbor(paths.get(66));
        paths.get(41).addNeighbor(paths.get(25));
        paths.get(41).addNeighbor(paths.get(29));
        paths.get(42).addNeighbor(paths.get(22));
        paths.get(42).addNeighbor(paths.get(47));
        paths.get(43).addNeighbor(paths.get(37));
        paths.get(43).addNeighbor(paths.get(49));
        paths.get(44).addNeighbor(paths.get(36));
        paths.get(44).addNeighbor(paths.get(66));
        paths.get(45).addNeighbor(paths.get(41));
        paths.get(45).addNeighbor(paths.get(55));
        paths.get(46).addNeighbor(paths.get(30));
        paths.get(46).addNeighbor(paths.get(32));
        paths.get(47).addNeighbor(paths.get(8));
        paths.get(47).addNeighbor(paths.get(67));
        paths.get(48).addNeighbor(paths.get(7));
        paths.get(48).addNeighbor(paths.get(68));
        paths.get(49).addNeighbor(paths.get(17));
        paths.get(49).addNeighbor(paths.get(19));
        paths.get(50).addNeighbor(paths.get(16));
        paths.get(50).addNeighbor(paths.get(20));
        paths.get(51).addNeighbor(paths.get(69));
        paths.get(51).addNeighbor(paths.get(71));
        paths.get(52).addNeighbor(paths.get(11));
        paths.get(52).addNeighbor(paths.get(70));
        paths.get(53).addNeighbor(paths.get(73));
        paths.get(53).addNeighbor(paths.get(75));
        paths.get(54).addNeighbor(paths.get(72));
        paths.get(54).addNeighbor(paths.get(74));
        paths.get(55).addNeighbor(paths.get(15));
        paths.get(55).addNeighbor(paths.get(19));
        paths.get(56).addNeighbor(paths.get(60));
        paths.get(56).addNeighbor(paths.get(62));
        paths.get(56).addNeighbor(paths.get(76));
        paths.get(57).addNeighbor(paths.get(25));
        paths.get(57).addNeighbor(paths.get(27));
        paths.get(57).addNeighbor(paths.get(77));
        paths.get(58).addNeighbor(paths.get(32));
        paths.get(58).addNeighbor(paths.get(34));
        paths.get(58).addNeighbor(paths.get(78));
        paths.get(59).addNeighbor(paths.get(14));
        paths.get(59).addNeighbor(paths.get(79));
        paths.get(60).addNeighbor(paths.get(80));
        paths.get(60).addNeighbor(paths.get(82));
        paths.get(61).addNeighbor(paths.get(51));
        paths.get(61).addNeighbor(paths.get(53));
        paths.get(61).addNeighbor(paths.get(81));
        paths.get(62).addNeighbor(paths.get(83));
        paths.get(62).addNeighbor(paths.get(84));
        paths.get(63).addNeighbor(paths.get(85));
        paths.get(63).addNeighbor(paths.get(86));
        paths.get(64).addNeighbor(paths.get(16));
        paths.get(64).addNeighbor(paths.get(18));
        paths.get(64).addNeighbor(paths.get(87));
        paths.get(65).addNeighbor(paths.get(15));
        paths.get(65).addNeighbor(paths.get(17));
        paths.get(65).addNeighbor(paths.get(88));
        paths.get(66).addNeighbor(paths.get(18));
        paths.get(66).addNeighbor(paths.get(20));
        paths.get(66).addNeighbor(paths.get(87));
        paths.get(67).addNeighbor(paths.get(6));
        paths.get(67).addNeighbor(paths.get(89));
        paths.get(68).addNeighbor(paths.get(5));
        paths.get(68).addNeighbor(paths.get(90));
        paths.get(69).addNeighbor(paths.get(91));
        paths.get(69).addNeighbor(paths.get(92));
        paths.get(70).addNeighbor(paths.get(3));
        paths.get(70).addNeighbor(paths.get(90));
        paths.get(71).addNeighbor(paths.get(73));
        paths.get(71).addNeighbor(paths.get(93));
        paths.get(72).addNeighbor(paths.get(85));
        paths.get(72).addNeighbor(paths.get(94));
        paths.get(73).addNeighbor(paths.get(95));
        paths.get(73).addNeighbor(paths.get(96));

        paths.get(74).addNeighbor(paths.get(0));

        paths.get(75).addNeighbor(paths.get(0));
        paths.get(76).addNeighbor(paths.get(0));
        paths.get(77).addNeighbor(paths.get(0));
        paths.get(78).addNeighbor(paths.get(0));
        paths.get(79).addNeighbor(paths.get(0));
        paths.get(80).addNeighbor(paths.get(0));
        paths.get(81).addNeighbor(paths.get(0));
        paths.get(82).addNeighbor(paths.get(0));
        paths.get(83).addNeighbor(paths.get(0));
        paths.get(84).addNeighbor(paths.get(0));
        paths.get(85).addNeighbor(paths.get(0));
        paths.get(86).addNeighbor(paths.get(0));
        paths.get(87).addNeighbor(paths.get(0));
        paths.get(88).addNeighbor(paths.get(0));
        paths.get(89).addNeighbor(paths.get(0));
        paths.get(90).addNeighbor(paths.get(0));
        paths.get(91).addNeighbor(paths.get(0));
        paths.get(92).addNeighbor(paths.get(0));
        paths.get(93).addNeighbor(paths.get(0));
        paths.get(94).addNeighbor(paths.get(0));
        paths.get(95).addNeighbor(paths.get(0));
        paths.get(96).addNeighbor(paths.get(0));
    }

    public void loadGame() {
        loadScene();
        loadPlayer();

        pts.setText("Pontos: " + String.valueOf(pontos));
        pts.setLocalTranslation(
                settings.getWidth() / 1.2f - guiFont.getCharSet().getRenderedSize() / 3 * 2,
                settings.getHeight() / 1.15f + pts.getLineHeight() / 2, 0);

        siren = new AudioNode(assetManager, "Sounds/siren.wav", true);
        siren.setLooping(true);
        siren.setPositional(true);
        siren.setVolume(3);
        rootNode.attachChild(siren);

        eating = new AudioNode(assetManager, "Sounds/eating.wav", false);
        eating.setPositional(false);
        eating.setLooping(false);
        eating.setVolume(10);
        rootNode.attachChild(eating);

        dies = new AudioNode(assetManager, "Sounds/dies.wav", false);
        dies.setPositional(false);
        dies.setLooping(false);
        dies.setVolume(10);
        rootNode.attachChild(dies);
    }
//</editor-fold>

    private Ghost getGhost(String name, Vector3f position) {
        Ghost g = new Ghost(name, position, assetManager);
        rootNode.attachChild(g.getModel());
        bulletAppState.getPhysicsSpace().add(g.getModel());
        return g;
    }

    private Geometry getBrick(String name, Vector3f position) {
        Box b = new Box(Vector3f.ZERO, 1.5f, 2, 1.5f);
        Geometry geom = new Geometry(name, b);
        geom.setLocalTranslation(position);
        geom.setMaterial(bmat);
        RigidBodyControl body = new RigidBodyControl(0.0f);
        geom.addControl(body);
        bulletAppState.getPhysicsSpace().add(body);
        body.setPhysicsLocation(position);
        return geom;
    }

    private Geometry getSphere(String name, Vector3f position, boolean special) {
        Ball geom = new Ball(name, special);
        geom.setMaterial(special ? spmat : smat);
        geom.setLocalTranslation(position);
        RigidBodyControl body = new RigidBodyControl(0.0f);
        geom.addControl(body);
        bulletAppState.getPhysicsSpace().add(body);
        body.setPhysicsLocation(position);
        body.setCollisionGroup(2);
        body.removeCollideWithGroup(2);
        return geom;
    }

    private Geometry getFloor() {
        Box floor = new Box(Vector3f.ZERO, 28.5f, 0.1f, 33f);
        floor.scaleTextureCoordinates(new Vector2f(3, 6));
        Geometry geom = new Geometry("Floor", floor);
        geom.setLocalTranslation(new Vector3f(28.5f, -0.1f, -33f));
        geom.setMaterial(fmat);
        RigidBodyControl body = new RigidBodyControl(0.0f);
        geom.addControl(body);
        bulletAppState.getPhysicsSpace().add(body);
        body.setPhysicsLocation(new Vector3f(28.5f, -0.1f, -33f));
        return geom;
    }

    private Geometry getCeil() {
        Box floor = new Box(Vector3f.ZERO, 28.5f, 0.1f, 33f);
        floor.scaleTextureCoordinates(new Vector2f(3, 6));
        Geometry geom = new Geometry("Ceil", floor);
        geom.setLocalTranslation(new Vector3f(28.5f, 4.1f, -33f));
        geom.setMaterial(cmat);
        RigidBodyControl body = new RigidBodyControl(0.0f);
        geom.addControl(body);
        bulletAppState.getPhysicsSpace().add(body);
        body.setPhysicsLocation(new Vector3f(28.5f, 4.1f, -33f));
        return geom;
    }

    @Override
    public void collision(PhysicsCollisionEvent event) {
        String a = event.getNodeA() != null ? event.getNodeA().getName() : "";
        String b = event.getNodeB() != null ? event.getNodeB().getName() : "";
        Ball ball;

        if (a.contains("Floor") || b.contains("Floor") || a.contains("Brick") || b.contains("Brick")) {
            return;
        }

        if (a.contains("Sphere")) {
            ball = (Ball) event.getNodeA();
            ball.setAlive(false);
            eating.playInstance();
            if (ball.isSpecial()) {
                player.setPowerful(true);
                player.setPTime(System.currentTimeMillis());
            }
            bulletAppState.getPhysicsSpace().remove(ball);
        } else if (a.contains("Ghost")) {
            if (player.isPowerful()) {
                ghosts.get(Integer.parseInt(a.replaceFirst("Ghost", "")))
                        .getBody().setEnabled(false);
            } else {
                player.setAlive(false);
                bulletAppState.getPhysicsSpace().remove(player);
                siren.stop();
                dies.playInstance();
            }
        }

        if (b.contains("Sphere")) {
            ball = (Ball) event.getNodeB();
            ball.setAlive(false);
            eating.playInstance();
            if (ball.isSpecial()) {
                player.setPowerful(true);
                player.setPTime(System.currentTimeMillis());
            }
            bulletAppState.getPhysicsSpace().remove(ball);
        } else if (b.contains("Ghost")) {
            if (player.isPowerful()) {
                ghosts.get(Integer.parseInt(b.replaceFirst("Ghost", "")))
                        .getBody().setEnabled(false);
            } else {
                player.setAlive(false);
                bulletAppState.getPhysicsSpace().remove(player);
                siren.stop();
                dies.playInstance();
            }
        }
    }

    @Override
    public void simpleUpdate(float tpf) {
        if (playing) {
            updateInGame(tpf);
        }
    }

    private void updateInGame(float tpf) {
        if (player.isPowerful()
                && (player.getPTime() + 10000 <= System.currentTimeMillis())) {
            player.setPowerful(false);
        }
        Node remove = new Node();
        for (Spatial ball : balls.getChildren()) {
            if (!((Ball) ball).isAlive()) {
                remove.attachChild(ball);
            }
        }
        if (remove.getChildren().size() > 0) {
            pontos += remove.getChildren().size();
            for (Spatial ball : remove.getChildren()) {
                balls.detachChild(ball);
            }
            remove.detachAllChildren();
        }
        for (Ghost g : ghosts) {
            if (!g.getBody().isEnabled()) {
                pontos += 100;
                g.resetPath(paths.get(0));
            }
            g.update();
        }

        if (player.isAlive()) {
            pts.setText("Pontos: " + String.valueOf(pontos));
            camDir.set(cam.getDirection()).multLocal(0.1f);
            camLeft.set(cam.getLeft()).multLocal(0.1f);
            player.setViewDirection(cam.getDirection());

            player.walk(camDir, camLeft);

            Vector3f pos = player.getPhysicsLocation();
            pos.setY(1.5f);
            cam.setLocation(pos);
        } else {
            guiNode.detachChild(pts);
            setPlaying(false, false);
            pause = true;
            controller.gameOver();
        }
    }

    @Override
    public void simpleInitApp() {
        setDisplayFps(false);
        setDisplayStatView(false);
        loadMaterials();
        flyCam.setMoveSpeed(3);

        setUpLight();
        setUpKeys();

        guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
        pts = new BitmapText(guiFont, false);
        pts.setSize(guiFont.getCharSet().getRenderedSize());

        placar = new TreeMap<>(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });

        loadPhysics();
        loadPaths();
        loadGame();

        cam.setFrustumNear(0.73f);
        controller = new niftyController(this);

        this.setPlaying(false, false);

    }

    //<editor-fold defaultstate="collapsed" desc="Setup">
    private void setUpLight() {
        DirectionalLight sun = new DirectionalLight();
        sun.setDirection(new Vector3f(-0.1f, -0.7f, -1.0f));
        rootNode.addLight(sun);
    }

    private void setUpKeys() {
        inputManager.addMapping("Left", new KeyTrigger(KeyInput.KEY_A));
        inputManager.addMapping("Right", new KeyTrigger(KeyInput.KEY_D));
        inputManager.addMapping("Up", new KeyTrigger(KeyInput.KEY_W));
        inputManager.addMapping("Down", new KeyTrigger(KeyInput.KEY_S));
        inputManager.addMapping("Restart", new KeyTrigger(KeyInput.KEY_R));
        inputManager.addMapping("Pause", new KeyTrigger(KeyInput.KEY_P));
        inputManager.addMapping("PlaySounds", new KeyTrigger(KeyInput.KEY_PGUP));
        inputManager.addMapping("PausarSounds", new KeyTrigger(KeyInput.KEY_PGDN));

        inputManager.addListener(this, "Left");
        inputManager.addListener(this, "Right");
        inputManager.addListener(this, "Up");
        inputManager.addListener(this, "Down");
        inputManager.addListener(this, "Restart");
        inputManager.addListener(this, "Pause");
        inputManager.addListener(this, "PlaySounds");
        inputManager.addListener(this, "PausarSounds");
    }
//</editor-fold>

    public void restartGame() {

        pause = false;
        siren.stop();
        rootNode.detachAllChildren();
        bulletAppState.getPhysicsSpace().destroy();
        bulletAppState.getPhysicsSpace().create();
        loadGame();
        startGame();
    }

    private void pauseGame() {
        if (playing) {
            guiNode.detachChild(pts);
            siren.pause();
            for (Ghost g : ghosts) {
                g.getModel().getControl(MyMotionControl.class).pause();
            }
            setPlaying(false, false);
            pause = true;
            controller.pauseGame();
        }
    }

    public void resumeGame() {
        guiNode.attachChild(pts);
        pause = false;
        siren.play();
        for (Ghost g : ghosts) {
            g.getModel().getControl(MyMotionControl.class).play();
        }
    }

    @Override
    public void onAction(String binding, boolean isPressed, float tpf) {
        if (!pause) {
            if ("Restart".equals(binding) && isPressed) {
                restartGame();
            } else if ("Pause".equals(binding) && isPressed) {
                pauseGame();
            } else if ("PlaySounds".equals(binding) && isPressed) {
                siren.setVolume(3);
                eating.setVolume(10);
                dies.setVolume(10);
            } else if ("PausarSounds".equals(binding) && isPressed) {
                siren.setVolume(0);
                eating.setVolume(0);
                dies.setVolume(0);
            } else {
                player.setDirection(binding, isPressed);
            }
        }
    }

    public void setPlaying(boolean play, boolean camPos) {
        this.playing = play;
        flyCam.setEnabled(camPos);
    }

    public TreeMap getPlacar() {
        return placar;
    }

    public void salvaPlacar(String nome) {
        placar.put(pontos, nome);
    }

    public Boolean isPaused() {
        return pause;
    }

    public int getPontos() {
        return this.pontos;
    }
}
